package Multithread.Thread;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;



/**
 * 1 线程的三种创建方式
 * 1.1 直接使用Thread
 * 1.2 使用 Runnable 配合 Thread
 * 1.3 FutureTask 配合 Callable
 * 1.3.1 返回值
 * 1.3.2 在线程中获取线程对象
 */
public class Thread01 {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        1.直接使用Thread (把线程和任务合并在一起)
//        runThread01();

//        2.使用 Runnable 配合 Thread
//        runThread02();

//        3.使用FutureTask配合Callable创建线程，这种方式下，线程可以返回值（以及如何在线程中获取线程对象）
        runThread03();

    }

    /**
     * @runThread01
     * 直接使用Thread (把线程和任务合并在一起)
     */
    public static void runThread01(){
        // 构造方法的参数是给线程指定名字，推荐
        Thread t1 = new Thread("t1") {
            @Override
            // run 方法内实现了要执行的任务
            public void run() {
                System.out.println("this is runThread01");
            }
        };
        t1.start();
    }

    /**
     * @runThread02
     * 使用 Runnable 配合 Thread
     * Thread 代表线程
     * Runnable 可运行的任务（线程要执行的代码）
     * 用 Runnable 更容易与线程池等高级 API 配合
     * 用 Runnable 让任务类脱离了 Thread 继承体系，更灵活
     */
    public static void runThread02(){

//        Runnable runnable = new Runnable() {
//            @Override
//            public void run(){
//                // 要执行的任务
//            }
//        };

        Runnable runnable = () -> {
            System.out.println("this is runThread02");
        };

        // 创建线程对象
        Thread t = new Thread( runnable );
        // 启动线程
        t.start();
    }

    /**
     * FutureTask 配合 Callable
     */
    public static void runThread03() throws ExecutionException, InterruptedException {
//        创建任务对象
//        FutureTask 能够接收 Callable 类型的参数，用来处理有返回结果的情况

//        旧写法
//        FutureTask<Integer> task4 = new FutureTask<>(new Callable<Integer>() {
//            @Override
//            public Integer call() throws Exception {
//                System.out.println("this is runThread03");
//                System.out.println(Thread.currentThread().getName());
//                return 100;
//            }
//        });

//        新写法
        FutureTask<Integer> task3 = new FutureTask<>(() -> {
            System.out.println("this is runThread03");
            System.out.println(Thread.currentThread().getName());
            return 100;
        });



        // 参数1 是任务对象; 参数2 是线程名字，推荐
        new Thread(task3, "t3").start();

        // 主线程阻塞，同步等待 task 执行完毕的结果
        Integer result = task3.get();
        System.out.println(result);


    }

}
